package example.runner;

import java.awt.Point;

import service.network.NetworkCalculationService;
import materials.network.NetworkInterface;

/**
 * Rennt durch das Feld und soll so viel essen wie möglich
 * @author Ramox
 */
public class Runner
{
	private int _eats; //Anzahl der gefutterten Essen
	private int _steps; //Anzahl der wirklich gelaufenen schritte
	private int _live; //Leben eines Runners
	private int _x;
	private int _y;
	
	private NetworkInterface _netz; // Neuronales Netz
	
	/**
 	 * Erzeugt den Runenr	
	 * @param netz Netz des Runners
	 */
	public Runner(NetworkInterface netz)
	{
		_eats = 0;
		_steps = 0;
		_netz = netz;
		_live = 40;
		arr = new double[8];
		for(int i = 0; i < arr.length; i++){
			arr[i] = 0;
		}
	}
	
	/**
	 * Gibt das Netz zurück
	 * @return netz des runners
	 */
	public NetworkInterface getNet()
	{
		return _netz;
	}

	/**
	 * Gibt die Fitness des Runners aus
	 * @return Fitness des Runners
	 */
	public double getFitness()
	{
		return _eats;
	}

	/**
	 * Berechnet die Richtung in der der Runner seinen nächsten schritt machen will.
	 * 
	 * @param umgebung umgebung um den Runner (5x5)
	 * 
	 * @return Richtung in die der Runner gehen will
	 */
	double[] arr;
	
	public Direction getNextDirection(FieldValues[] umgebung)
	{
		NetworkCalculationService ncs = new NetworkCalculationService(_netz);
		double[] inputvector = new double[33];

		
		//input für das netz
		for (int i = 0; i < 25; i++)
		{
			if (umgebung[i] == FieldValues.Essen) //essen
			{
				inputvector[i] = 100;
			}
			else if (umgebung[i] == FieldValues.Frei) //leer
			{
				inputvector[i] = 10;
			}
			else if (umgebung[i] == FieldValues.Runner) //leer
			{
				inputvector[i] = -10;
			}
			else if(umgebung[i] == FieldValues.Wand)//wand und andere runner
			{
				inputvector[i] = -100;
			}
		}
		for(int i = 25; i < 34; i++){
			inputvector[i] = arr[(i-25)];
		}
		
		for(double v : inputvector){
			//System.out.print( "(" + v +")" + "-");
		}
		//System.out.println();
		
		double[] nri = ncs.calculateInput(inputvector);
		for(int i = 0; i < nri.length; i++){
			arr[i] = nri[i];
		}
	//	System.out.println(nri.length);
		for(double v : nri)
		{
			String wert = String.valueOf(v);
			if(wert.length() > 4){
				wert = 
					wert.substring(0,4);
			}
			
		}
		//berechnung der Ausgabe (51-58 sind die Neuronen in Layer 3)
		
		double maximum = 0;
		int index = 0;
		
		for (int i = 0; i < 8; i++)
		{
			if (nri[i] > maximum)
			{
				maximum = nri[i];
				index = i;
			}
		}
		
		//Richtung des Neuronen mit der größten Ausgabe ist die gewünschte
		return Direction.values()[index];
	}

	/**
	 * erhöht die Anzahl der Essen
	 */
	public void increaseHealth()
	{
		_eats++;
	}

	/**
	 * erniedrigt die anzahl der Essen, wenn ein runner gegen die Wand läuft z.b.
	 */
	public void decreaseHealth()
	{
		//_eats--; 
	}

	/**
	 * erhöht die anzahl der schritte
	 */
	public void increaseSteps()
	{
		_steps++;
	}

	public void increaseLive(){
		_live++;
	}

	public void setPosition(int x, int y) {
		_x = x;
		_y = y;
	}
	
	public Point getPosition(){
		return new Point(_x,_y);
	}

	public void decreaseLive() {
		//_eats--;
	}


}
